package com.example.score.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.score.entity.*;
import com.example.score.mapper.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ReportService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private ExamDetailMapper examDetailMapper;

    @Autowired
    private ClassInfoMapper classInfoMapper;

    @Autowired
    private StudentSubmitMapper studentSubmitMapper;

    @Autowired
    private QuestionScoreMapper questionScoreMapper;

    @Autowired
    private QuestionInfoMapper questionInfoMapper;

    @Autowired
    private ScoreStatisticsMapper scoreStatisticsMapper;

    @Autowired
    private ScoreDetailMapper scoreDetailMapper;

    @Autowired
    private ScoreDetailQuestionMapper scoreDetailQuestionMapper;

    @Autowired
    private SubmitStatisticsMapper submitStatisticsMapper;

    private static final String REPORT_QUEUE_KEY = "exam:report:queue";
    @Autowired
    private HighErrorQuestionStatisticsMapper highErrorQuestionStatisticsMapper;

    //    @Scheduled(fixedDelay = 5000) // 每5秒执行一次
    @Transactional
    public void processReportQueue() {
        try {
            // 从队列中获取考试详情ID
            Object examDetailId = redisTemplate.opsForList().leftPop(REPORT_QUEUE_KEY);
            if (examDetailId == null) {
                return;
            }

            log.info("开始处理报表数据: examDetailId={}", examDetailId);

            // 1. 生成成绩概览
            generateScoreOverview(Long.valueOf(examDetailId.toString()));

            // 2. 生成作业得分表
            generateScoreTable(Long.valueOf(examDetailId.toString()));

            // 3. 生成高频错题统计
            generateFrequentWrongQuestions(Long.valueOf(examDetailId.toString()));

            // 4. 生成提交作业统计
            generateSubmitStatistics(Long.valueOf(examDetailId.toString()));

            log.info("报表数据处理完成: examDetailId={}", examDetailId);
        } catch (Exception e) {
            log.error("处理报表数据失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 生成成绩概览
     * 包含：满分/最高分/平均分/优秀率/及格率/中位数/标准差
     */
    private void generateScoreOverview(Long examDetailId) {
        try {
            // 1. 获取考试详情
            ExamDetail examDetail = examDetailMapper.selectById(examDetailId);
            if (examDetail == null) {
                log.error("未找到考试详情: examDetailId={}", examDetailId);
                return;
            }

            // 2. 获取班级信息
            List<ClassInfo> classInfos = classInfoMapper.selectList(
                    new QueryWrapper<ClassInfo>().eq("exam_detail_id", examDetailId)
            );

            // 3. 获取所有学生提交记录
            List<StudentSubmit> allStudentSubmits = studentSubmitMapper.selectList(
                    new QueryWrapper<StudentSubmit>().eq("exam_detail_id", examDetailId)
            );

            List<Long> studentSubmitIds = allStudentSubmits.stream().map(StudentSubmit::getId).collect(Collectors.toList());
            // 4. 获取所有题目得分
            List<QuestionScore> allQuestionScores = questionScoreMapper.selectListBySubmitIds(studentSubmitIds);
            // 4. 获取所有题目得分
            List<QuestionInfo> questionInfos = questionInfoMapper.selectList(
                    new QueryWrapper<QuestionInfo>().in("exam_detail_id", examDetailId)
            );
            Map<Long, QuestionInfo> questionInfoMap = questionInfos.stream().collect(
                    Collectors.toMap(QuestionInfo::getQuestionId, Function.identity()));

            // 5. 按班级组织数据
            Map<Long, List<StudentSubmit>> classStudentMap = allStudentSubmits.stream()
                    .collect(Collectors.groupingBy(StudentSubmit::getClassInfoId));

            // 6. 按学生组织题目得分
            Map<Long, List<QuestionScore>> studentScoreMap = allQuestionScores.stream()
                    .collect(Collectors.groupingBy(QuestionScore::getStudentSubmitId));

            // 7. 统计每个班级的成绩
            List<ScoreStatistics> allStatistics = new ArrayList<>();

            // 添加日志来检查班级ID
            for (ClassInfo classInfo : classInfos) {
                log.info("处理班级信息: classInfoId={}, classId={}, className={}",
                        classInfo.getId(), classInfo.getClassId(), classInfo.getClassName());

                List<StudentSubmit> classStudents = classStudentMap.get(classInfo.getId());
                if (classStudents == null) continue;

                ScoreStatistics statistics = calculateStatistics(
                        examDetail, classInfo, classStudents, studentScoreMap,
                        questionInfoMap);
                allStatistics.add(statistics);
            }

            int sum = allStatistics.stream().mapToInt(ScoreStatistics::getTotalStudents).sum();

            // 年级汇总使用特殊的ID
            if (!allStatistics.isEmpty()) {
                ClassInfo gradeInfo = new ClassInfo();
                gradeInfo.setId(0L);
                gradeInfo.setClassId(-1L);  // 使用一个明确不会与实际班级ID冲突的值
                gradeInfo.setClassName("年级汇总");
                gradeInfo.setStudentCount(sum);

                ScoreStatistics gradeStatistics = calculateStatistics(
                        examDetail,
                        gradeInfo,
                        allStudentSubmits,
                        studentScoreMap,
                        questionInfoMap
                );

                // 添加日志检查年级汇总的ID
                log.info("年级汇总信息: examDetailId={}, classId={}, className={}",
                        examDetailId, gradeInfo.getClassId(), gradeInfo.getClassName());

                allStatistics.add(gradeStatistics);
            }

            // 在批量插入前检查是否有重复的组合
            Map<String, Long> examClassCombinations = new HashMap<>();
            List<ScoreStatistics> uniqueStatistics = new ArrayList<>();

            for (ScoreStatistics stat : allStatistics) {
                String key = stat.getExamDetailId() + "-" + stat.getClassId();
                if (!examClassCombinations.containsKey(key)) {
                    examClassCombinations.put(key, stat.getClassId());
                    uniqueStatistics.add(stat);
                } else {
                    log.warn("发现重复的考试-班级组合: examDetailId={}, classId={}, className={}",
                            stat.getExamDetailId(), stat.getClassId(), stat.getClassName());
                }
            }

            // 保存前打印每条记录的关键信息
            log.info("准备保存统计结果，数据量: {}", uniqueStatistics.size());
            for (ScoreStatistics stat : uniqueStatistics) {
                log.info("统计记录: examDetailId={}, classId={}, className={}",
                        stat.getExamDetailId(), stat.getClassId(), stat.getClassName());
            }

            // 使用去重后的数据进行保存
            scoreStatisticsMapper.insertBatch(uniqueStatistics);

            log.info("成绩统计保存完成");
        } catch (Exception e) {
            log.error("成绩统计失败: examDetailId={}, error={}", examDetailId, e.getMessage(), e);
            throw e;
        }
    }

    private ScoreStatistics calculateStatistics(
            ExamDetail examDetail,
            ClassInfo classInfo,
            List<StudentSubmit> students,
            Map<Long, List<QuestionScore>> studentScoreMap,
            Map<Long, QuestionInfo> questionInfoMap
    ) {

        ScoreStatistics statistics = new ScoreStatistics();
        statistics.setExamDetailId(examDetail.getId());
        statistics.setClassId(classInfo.getClassId());
        statistics.setClassName(classInfo.getClassName());
        statistics.setFullScore(examDetail.getFullScore().doubleValue());

        // 计算基础统计数据
        statistics.setTotalStudents(classInfo.getStudentCount());
        statistics.setSubmitStudents(students.size());

        // 计算分数相关统计
        List<Double> scores = students.stream()
                .map(StudentSubmit::getScore)
                .sorted()
                .collect(Collectors.toList());

        if (!scores.isEmpty()) {
            statistics.setMaxScore(scores.get(scores.size() - 1));
            statistics.setAvgScore(scores.stream().mapToDouble(Double::doubleValue).average().orElse(0.0));

            // 计算中位数
            if (scores.size() % 2 == 0) {
                statistics.setMedianScore(
                        (scores.get(scores.size() / 2 - 1) + scores.get(scores.size() / 2)) / 2.0);
            } else {
                statistics.setMedianScore(scores.get(scores.size() / 2));
            }

            // 计算标准差
            double variance = scores.stream()
                    .mapToDouble(score -> Math.pow(score - statistics.getAvgScore(), 2))
                    .average()
                    .orElse(0.0);
            statistics.setStdDev(Math.sqrt(variance));

            // 计算优秀率和及格率
            long excellentCount = scores.stream()
                    .filter(score -> score >= statistics.getFullScore() * 0.85)
                    .count();
            long passCount = scores.stream()
                    .filter(score -> score >= statistics.getFullScore() * 0.60)
                    .count();

            statistics.setExcellentCount((int) excellentCount);
            statistics.setExcellentRate((double) excellentCount / scores.size());
            statistics.setPassCount((int) passCount);
            statistics.setPassRate((double) passCount / scores.size());

            // 计算客观题和主观题平均分
            Map<Long, Double> objectiveScores = new HashMap<>();
            Map<Long, Double> subjectiveScores = new HashMap<>();

            for (StudentSubmit student : students) {
                List<QuestionScore> questionScores = studentScoreMap.get(student.getId());
                if (questionScores == null) continue;

                double objectiveTotal = 0.0;
                double subjectiveTotal = 0.0;

                for (QuestionScore score : questionScores) {
                    QuestionInfo questionInfo = questionInfoMap.get(score.getQuestionId());
                    if (questionInfo.getIsSubjectiveItem() == 1) {
                        subjectiveTotal += score.getScore();
                    } else {
                        objectiveTotal += score.getScore();
                    }
                }

                objectiveScores.put(student.getId(), objectiveTotal);
                subjectiveScores.put(student.getId(), subjectiveTotal);
            }

            statistics.setObjectiveAvgScore(
                    objectiveScores.values().stream().mapToDouble(Double::doubleValue).average().orElse(0.0));
            statistics.setSubjectiveAvgScore(
                    subjectiveScores.values().stream().mapToDouble(Double::doubleValue).average().orElse(0.0));
        }

        return statistics;
    }

    /**
     * 生成作业得分表
     * 维度：班级/考号/姓名/总分/客观题/主观题/各题得分及得分率
     */
    private void generateScoreTable(Long examDetailId) {
        try {
            // 1. 先检查是否已经生成过
            if (scoreDetailMapper.selectCount(
                    new QueryWrapper<ScoreDetailStatistics>().eq("exam_detail_id", examDetailId)) > 0) {
                log.info("作业得分表已存在，跳过生成: examDetailId={}", examDetailId);
                return;
            }

            // 1. 获取考试详情
            ExamDetail examDetail = examDetailMapper.selectById(examDetailId);
            if (examDetail == null) {
                log.error("未找到考试详情: examDetailId={}", examDetailId);
                return;
            }

            // 2. 获取班级信息
            List<ClassInfo> classInfos = classInfoMapper.selectList(
                    new QueryWrapper<ClassInfo>().eq("exam_detail_id", examDetailId)
            );
            Map<Long, ClassInfo> mapClassInfoId2Entity = classInfos.stream().collect(Collectors.toMap(ClassInfo::getId, Function.identity()));
            log.info("总班级数: {}", classInfos.size());

            // 3. 获取所有学生提交记录
            List<StudentSubmit> studentSubmits = studentSubmitMapper.selectList(
                    new QueryWrapper<StudentSubmit>().eq("exam_detail_id", examDetailId)
            );

            log.info("总提交学生数: {}", studentSubmits.size());

            // 按班级统计提交人数
            Map<Long, Long> classSubmitCounts = studentSubmits.stream()
                    .collect(Collectors.groupingBy(StudentSubmit::getClassInfoId, Collectors.counting()));

            // 打印每个班级的提交情况
            for (ClassInfo classInfo : classInfos) {
                Long submitCount = classSubmitCounts.getOrDefault(classInfo.getId(), 0L);
                log.info("班级提交情况 - 班级: {}, 总人数: {}, 提交人数: {}, 未提交人数: {}",
                        classInfo.getClassName(),
                        classInfo.getStudentCount(),
                        submitCount,
                        classInfo.getStudentCount() - submitCount);
            }
            List<Long> studentSubmitIds = studentSubmits.stream().map(StudentSubmit::getId).collect(Collectors.toList());
            // 5. 获取所有题目得分
            List<QuestionScore> questionScores = questionScoreMapper.selectListBySubmitIds(studentSubmitIds);

            log.info("总题目得分记录数: {}", questionScores.size());

            // 6. 按学生组织题目得分
            Map<Long, List<QuestionScore>> studentScoreMap = questionScores.stream()
                    .collect(Collectors.groupingBy(QuestionScore::getStudentSubmitId));

            log.info("有题目得分的学生数: {}", studentScoreMap.size());

            // 检查是否有学生提交了但没有题目得分
            Set<Long> submittedStudentIds = studentSubmits.stream()
                    .map(StudentSubmit::getId)
                    .collect(Collectors.toSet());
            Set<Long> scoredStudentIds = studentScoreMap.keySet();
            Set<Long> missingScoreStudents = new HashSet<>(submittedStudentIds);
            missingScoreStudents.removeAll(scoredStudentIds);

            if (!missingScoreStudents.isEmpty()) {
                log.warn("发现{}个学生提交了但没有题目得分记录", missingScoreStudents.size());
                for (Long studentSubmitId : missingScoreStudents) {
                    StudentSubmit submit = studentSubmits.stream()
                            .filter(s -> s.getId().equals(studentSubmitId))
                            .findFirst()
                            .orElse(null);
                    if (submit != null) {
                        log.warn("缺失题目得分的学生: studentId={}, studentName={}, classInfoId={}",
                                submit.getStudentId(), submit.getStudentName(), submit.getClassInfoId());
                    }
                }
            }

            // 7. 准备批量插入的数据
            Map<String, ScoreDetailStatistics> scoreDetailMap = new HashMap<>();
            Map<String, List<ScoreDetailQuestionStatistics>> questionDetailsMap = new HashMap<>();

            // 获取所有题目信息并建立映射
            List<QuestionInfo> allQuestions = questionInfoMapper.selectList(
                    new QueryWrapper<QuestionInfo>()
                            .eq("exam_detail_id", examDetailId)
            );
            Map<Long, QuestionInfo> questionMap = allQuestions.stream()
                    .collect(Collectors.toMap(QuestionInfo::getQuestionId, Function.identity()));

            // 记录题目数量，避免重复查询
            final int questionCount = allQuestions.size();

            // 8. 处理每个学生的成绩
            int processedCount = 0;
            int skippedCount = 0;
            for (StudentSubmit submit : studentSubmits) {
                List<QuestionScore> scores = studentScoreMap.get(submit.getId());
                if (scores == null) {
                    skippedCount++;
                    log.warn("学生没有题目得分记录: studentId={}, studentName={}, classInfoId={}",
                            submit.getStudentId(), submit.getStudentName(), submit.getClassInfoId());
                    continue;
                }
                processedCount++;

                // 计算客观题和主观题得分
                double objectiveScore = 0.0;
                double subjectiveScore = 0.0;
                Map<Long, Double> questionScoreMap = new HashMap<>();

                // 使用已经查询好的题目信息
                for (QuestionScore score : scores) {
                    QuestionInfo question = questionMap.get(score.getQuestionId());
                    if (question == null) {
                        log.warn("未找到题目信息: questionId={}", score.getQuestionId());
                        continue;
                    }

                    questionScoreMap.put(question.getQuestionId(), score.getScore());
                    if (question.getIsSubjectiveItem() == 1) {
                        subjectiveScore += score.getScore();
                    } else {
                        objectiveScore += score.getScore();
                    }
                }
                ClassInfo classInfo = mapClassInfoId2Entity.get(submit.getClassInfoId());
                // 创建得分明细
                ScoreDetailStatistics scoreDetailStatistics = new ScoreDetailStatistics();
                scoreDetailStatistics.setExamDetailId(examDetail.getId());
                scoreDetailStatistics.setClassId(classInfo.getClassId());
                scoreDetailStatistics.setClassName(classInfo.getClassName());
                scoreDetailStatistics.setStudentId(submit.getStudentId().toString());
                scoreDetailStatistics.setStudentName(submit.getStudentName());
                scoreDetailStatistics.setTotalScore(submit.getScore());
                scoreDetailStatistics.setObjectiveScore(objectiveScore);
                scoreDetailStatistics.setSubjectiveScore(subjectiveScore);

                // 设置日期
                ZonedDateTime zonedDateTime = examDetail.getCreatedTime().atZone(ZoneId.systemDefault());
                Date date = Date.from(zonedDateTime.toInstant());
                scoreDetailStatistics.setExamDate(date);
                scoreDetailStatistics.setSubjectName(examDetail.getSubjectName());
                scoreDetailStatistics.setCreatedTime(new Date());
                scoreDetailStatistics.setUpdatedTime(new Date());

                // 创建题目得分明细
                List<ScoreDetailQuestionStatistics> studentQuestionDetails = new ArrayList<>();
                for (Map.Entry<Long, Double> entry : questionScoreMap.entrySet()) {
                    QuestionInfo question = questionMap.get(entry.getKey());
                    if (question == null) continue;

                    ScoreDetailQuestionStatistics detail = new ScoreDetailQuestionStatistics();
                    // 暂时不设置 scoreDetailId
                    detail.setQuestionType(question.getIsSubjectiveItem() == 1 ? 1 : 2);
                    detail.setQuestionNum(question.getQuestionNum().toString());
                    detail.setScore(entry.getValue());
                    detail.setScoreRate(entry.getValue() / question.getQuestionScore());
                    detail.setCreatedTime(new Date());
                    detail.setUpdatedTime(new Date());

                    studentQuestionDetails.add(detail);
                }

                // 使用唯一键保存映射关系
                String key = scoreDetailStatistics.getExamDetailId() + "_" +
                        scoreDetailStatistics.getClassId() + "_" +
                        scoreDetailStatistics.getStudentId();
                scoreDetailMap.put(key, scoreDetailStatistics);
                questionDetailsMap.put(key, studentQuestionDetails);
            }

            // 9. 批量保存得分明细
            List<ScoreDetailStatistics> scoreDetailStatistics = new ArrayList<>(scoreDetailMap.values());
            if (!scoreDetailMap.isEmpty()) {
                log.info("开始批量保存得分明细，数量: {}", scoreDetailStatistics.size());
                scoreDetailMapper.insertBatch(scoreDetailStatistics);

                // 现在 scoreDetails 中的每个对象都有了 ID
                List<ScoreDetailQuestionStatistics> allQuestionDetails = new ArrayList<>();
                for (ScoreDetailStatistics detailStatistics : scoreDetailStatistics) {
                    String key = detailStatistics.getExamDetailId() + "_" +
                            detailStatistics.getClassId() + "_" +
                            detailStatistics.getStudentId();
                    List<ScoreDetailQuestionStatistics> questionDetails = questionDetailsMap.get(key);
                    if (questionDetails != null) {
                        for (ScoreDetailQuestionStatistics detail : questionDetails) {
                            detail.setScoreDetailId(detailStatistics.getId());
                        }
                        allQuestionDetails.addAll(questionDetails);
                    }
                }

                if (!allQuestionDetails.isEmpty()) {
                    log.info("开始批量保存题目得分明细，数量: {}", allQuestionDetails.size());
                    scoreDetailQuestionMapper.insertBatch(allQuestionDetails);
                }
            }

            log.info("成绩明细处理完成: 总学生数={}, 处理学生数={}, 跳过学生数={}, 最终保存记录数={}",
                    classInfos.stream().mapToInt(ClassInfo::getStudentCount).sum(),
                    processedCount,
                    skippedCount,
                    scoreDetailStatistics.size());

        } catch (Exception e) {
            log.error("生成作业得分表失败: examDetailId={}, error={}", examDetailId, e.getMessage(), e);
            throw e;
        }
    }

    /**
     * 生成高频错题统计
     * 统计得分率<=40%的题目
     */
    public void generateFrequentWrongQuestions(Long examDetailId) {
        try {
            // 1. 获取所有题目信息
            List<QuestionInfo> questions = questionInfoMapper.selectList(
                    new QueryWrapper<QuestionInfo>().eq("exam_detail_id", examDetailId)
            );
            Map<Long, QuestionInfo> questionMap = questions.stream()
                    .collect(Collectors.toMap(QuestionInfo::getQuestionId, q -> q));
            // 2. 获取班级信息
            List<ClassInfo> classInfos = classInfoMapper.selectList(
                    new QueryWrapper<ClassInfo>().eq("exam_detail_id", examDetailId)
            );
            // 3. 获取所有学生提交记录
            List<StudentSubmit> studentSubmits = studentSubmitMapper.selectList(
                    new QueryWrapper<StudentSubmit>().in("class_info_id",
                            classInfos.stream().map(ClassInfo::getId).collect(Collectors.toList()))
            );
            // 4. 获取所有题目得分
            List<Long> studentSubmitIds = studentSubmits.stream().map(StudentSubmit::getStudentId).collect(Collectors.toList());
            List<QuestionScore> questionScores = questionScoreMapper.selectListBySubmitIds(studentSubmitIds);
            // 6. 计算每个班级每道题的得分率
            List<HighErrorQuestionStatistics> highErrorQuestionStatisticsList = new ArrayList<>();
            for(ClassInfo classInfo : classInfos) {
                //拿到班级所有的提交名单
                List<Long> submitIds = studentSubmits.stream().filter(studentSubmit -> studentSubmit.getClassInfoId().equals(classInfo.getId())).map(StudentSubmit::getId).collect(Collectors.toList());
                // 5. 按题目ID组织得分数据
                Map<Long, List<QuestionScore>> questionScoreMap = questionScores.stream().filter(q-> submitIds.contains(q.getStudentSubmitId()))
                        .collect(Collectors.groupingBy(QuestionScore::getQuestionId));
                for (QuestionInfo question : questions) {
                    List<QuestionScore> scores = questionScoreMap.get(question.getQuestionId());
                    if (scores == null) continue;
                    double totalScore = scores.stream().mapToDouble(QuestionScore::getScore).sum();
                    double maxPossibleScore = question.getQuestionScore() * scores.size();
                    double scoreRate = totalScore / maxPossibleScore;
                    if (scoreRate <= 0.4) {
                        HighErrorQuestionStatistics highErrorQuestionStatistics = new HighErrorQuestionStatistics();
                        highErrorQuestionStatistics.setQuestionId(question.getQuestionId());
                        highErrorQuestionStatistics.setExamDetailId(examDetailId);
                        highErrorQuestionStatistics.setClassInfoId(classInfo.getId());
                        highErrorQuestionStatistics.setClassId(classInfo.getClassId());
                        highErrorQuestionStatistics.setClassName(classInfo.getClassName());
                        highErrorQuestionStatistics.setScoreRate(scoreRate);
                        highErrorQuestionStatistics.setCreatedTime(LocalDateTime.now());
                        highErrorQuestionStatistics.setUpdatedTime(LocalDateTime.now());
                        highErrorQuestionStatisticsList.add(highErrorQuestionStatistics);
                    }
                }
            }
            if(!highErrorQuestionStatisticsList.isEmpty()) {
                highErrorQuestionStatisticsMapper.insertBatch(highErrorQuestionStatisticsList);
            }
            log.info("高频错题统计完成: examDetailId={}, wrongQuestions={}", examDetailId, highErrorQuestionStatisticsList);
        } catch (Exception e) {
            log.error("生成高频错题统计失败: examDetailId={}, error={}", examDetailId, e.getMessage(), e);
        }
    }

    // 实现提交作业统计方法
    public void generateSubmitStatistics(Long examDetailId) {
        try {
            // 1. 获取所有班级信息
            List<ClassInfo> classInfos = classInfoMapper.selectList(
                    new QueryWrapper<ClassInfo>()
                            .eq("exam_detail_id", examDetailId)
            );

            // 2. 获取所有提交记录
            List<StudentSubmit> allSubmits = studentSubmitMapper.selectList(
                    new QueryWrapper<StudentSubmit>()
                            .eq("exam_detail_id", examDetailId)
                            .eq("submit_status", 1)  // 只统计已完成的提交
            );
            // 获取所有题目信息
            List<QuestionInfo> questions = questionInfoMapper.selectByExamDetailId(examDetailId);

            // 3. 按班级分组统计
            Map<Long, List<StudentSubmit>> classSubmits = allSubmits.stream()
                    .collect(Collectors.groupingBy(StudentSubmit::getClassInfoId));
            List<SubmitStatistics> statisticsList = new ArrayList<>();
            // 4. 处理每个班级的统计
            for (ClassInfo classInfo : classInfos) {
                List<StudentSubmit> submits = classSubmits.getOrDefault(classInfo.getId(), new ArrayList<>());
                // 批量获取所有题目得分
                Map<Long, List<QuestionScore>> questionScoresMap = new HashMap<>();

                // 统计实际提交人数（去重）
                Set<Long> submitStudentIds = submits.stream()
                        .map(StudentSubmit::getStudentId)
                        .collect(Collectors.toSet());
                int submitCount = submitStudentIds.size();
                //计算班级空白提交率
                double blankRate = getBlankSubmitRate(submits, questionScoresMap, questions);
                SubmitStatistics statistics = new SubmitStatistics();
                statistics.setExamDetailId(examDetailId);
                statistics.setClassId(classInfo.getClassId());
                statistics.setClassInfoId(classInfo.getId());
                statistics.setGradeInfoId(classInfo.getGradeInfoId());
                statistics.setClassName(classInfo.getClassName());
                statistics.setTotalStudents(classInfo.getStudentCount());
                statistics.setSubmitStudents(submitCount);
                statistics.setMissingStudents(classInfo.getStudentCount() - submitCount);
                statistics.setBlankSubmitRate(0.0);
                statistics.setCreatedTime(new Date());
                statistics.setUpdatedTime(new Date());
                statisticsList.add(statistics);
            }
            // 5. 批量保存统计结果
            if (!statisticsList.isEmpty()) {
                // 先删除旧数据
                submitStatisticsMapper.delete(
                        new QueryWrapper<SubmitStatistics>()
                                .eq("exam_detail_id", examDetailId)
                );
                // 插入新数据
                submitStatisticsMapper.insertBatch(statisticsList);
            }
            log.info("提交作业统计完成: examDetailId={}, 统计班级数={}", examDetailId, statisticsList.size());
        } catch (Exception e) {
            log.error("生成提交作业统计失败: examDetailId={}, error={}", examDetailId, e.getMessage(), e);
            throw e;
        }
    }

    private double getBlankSubmitRate(List<StudentSubmit> submits, Map<Long, List<QuestionScore>> questionScoresMap, List<QuestionInfo> questions) {
        double blankRate = 0.0;
        List<Long> submitIds = submits.stream().map(StudentSubmit::getId).collect(Collectors.toList());
        if (!submitIds.isEmpty()) {
            List<QuestionScore> allScores = questionScoreMapper.selectByStudentSubmitIds(submitIds);
            questionScoresMap = allScores.stream()
                    .collect(Collectors.groupingBy(QuestionScore::getQuestionId));
        }
        // 按题目统计空白率
        for (QuestionInfo question : questions) {
            Map<String, Object> stat = new HashMap<>();
            // 从Map中获取该题目的所有得分记录
            List<QuestionScore> scores = questionScoresMap.getOrDefault(question.getQuestionId(), Collections.emptyList());
            if (!scores.isEmpty()) {
                // 计算空白率
                long blankCount;
                if (question.getIsSubjectiveItem() == 1) {
                    // 主观题：检查答案是否为空
                    blankCount = scores.stream()
                            .filter(s -> s.getStudentAnswer() == null || s.getStudentAnswer().trim().isEmpty())
                            .count();
                } else {
                    // 客观题：检查得分是否为0
                    blankCount = scores.stream()
                            .filter(s -> Math.abs(s.getScore()) == 0 && s.getStudentAnswer() == null )
                            .count();
                }
                blankRate = (double) blankCount / scores.size() * 100;
            }
        }
        return blankRate;
    }

}